package com.efounder.message.socket;

import android.util.Log;

import com.efounder.message.socket.JFSocketHandler.OnChannelActiveListener;
import com.efounder.message.struct.IMStruct000;
import com.efounder.util.AppContext;
import com.efounder.util.LogUtils;

import java.net.InetSocketAddress;
import java.util.Timer;
import java.util.TimerTask;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;


public class JFSocketManager {
    private static final String TAG = "JFSocketManager";

    private static int TIME_OUT = 20;
    private static boolean READ_TIME_OUT = false;
    private static boolean WRITE_TIME_OUT = false;
    private static int HEARTBEAT = 10000;
    public static String URL = "192.168.248.220";//"10.80.0.123";
    public static int PORT = 8000;//8000;
    public static String token = "";

    private IMStruct000 imStruct000 = new IMStruct000();

    private static Bootstrap bootstrap;
    private static NioEventLoopGroup group;
    private static Channel channel;
    private static ChannelFuture future;
    private JFSocketInitializer initializer;
    private OnChannelActiveListener onChannelActiveListener;

    private static JFSocketManager sockerManager;

    private Timer timer;
    private TimerTask timerTask;

    public static JFSocketManager getInstance() {
        if (sockerManager == null)
            sockerManager = new JFSocketManager();
        return sockerManager;
    }

    public void init() {
        if (bootstrap == null) {
            group = new NioEventLoopGroup();
            // Client服务启动器
            bootstrap = new Bootstrap();
            // 指定channel类型
            bootstrap.channel(NioSocketChannel.class);
            // 指定Handler
            initializer = new JFSocketInitializer();
            initializer.setOnChannelActiveListener(this.onChannelActiveListener);
//			bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000);
            bootstrap.handler(initializer);
            // 指定EventLoopGroup
            bootstrap.group(group);
        }

        start();
    }

    public void setOnChannelActiveListener(
            OnChannelActiveListener onChannelActiveListener) {
        this.onChannelActiveListener = onChannelActiveListener;
    }

    private void start() {
        // 连接到服务端
//        JFThreadPoolUtils.execute(new Runnable() {
//            @Override
//            public void run() {
        try {
            future = bootstrap.connect(new InetSocketAddress(URL, PORT)).sync();//awaitUninterruptibly()
//					future = bootstrap.connect(new InetSocketAddress("211.87.227.34", 8000)).sync();//awaitUninterruptibly()
//					channel = future.channel();
            future.awaitUninterruptibly(6000);
            if (future.isCancelled()) {
                // Connection attempt cancelled by user
                if (onChannelActiveListener != null) {
                    onChannelActiveListener.onChannelActiveFail();
                }
            } else if (!future.isSuccess()) {
                // You might get a NullPointerException here because the future
                // might not be completed yet.
                future.cause().printStackTrace();
                if (onChannelActiveListener != null) {
                    onChannelActiveListener.onChannelActiveFail();
                }
            } else {
                // Connection established successfully
                channel = future.channel();
                channel.read();
            }
        } catch (final Exception e) {
            if (onChannelActiveListener != null) {
                onChannelActiveListener.onChannelActiveFail();
            }
            if (AppContext.getCurrentActivity() != null && LogUtils.isDebugModel(AppContext.getInstance())) {
                AppContext.getCurrentActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Log.e(TAG, "socketManager_start()--" + e.getMessage());
                        //ToastUtil.showToast(AppContext.getInstance(),"socketManager_start()--" + e.getMessage());
                    }
                });
            }
            e.printStackTrace();
        }
//            }
//        });
    }

    public void startTimer() {
        //先停止之前的
        stopTimer();
        timer = new Timer();
        timerTask = new TimerTask() {
            @Override
            public void run() {
                Log.d(TAG, "向服务器发送心跳");
                JFSocketManager.sendMessage(imStruct000.toByteArray());
            }
        };
        timer.schedule(timerTask, HEARTBEAT, HEARTBEAT);
    }

    public void stopTimer() {
        if (timer != null) {
            try {
                timer.cancel();
                timer.purge();
                timer = null;
                timerTask = null;
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    public void stop() {
        try {
            if (channel != null) {
                channel.close().sync();
            }
            if (group != null) {
                group.shutdownGracefully().sync();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        bootstrap = null;
        group = null;
        channel = null;
        stopTimer();
    }

    public static boolean isChannelActived() {
        if (channel == null) return false;

        return channel.isActive();
    }

    public static void sendMessage(byte[] message) {
        JFSocketManager.sendMessage(message, "");
    }

    public static void sendMessage(byte[] message, String messageID) {
        try {
            //todo  yqs 这里增加判断 如果socket通道是关闭的，就不往下执行了
            if (!isChannelActived()) {
                return;
            }
            Log.d(TAG, "socketSendMessage------>" + new String(message, "utf-8"));
            ByteBuf buffer = Unpooled.buffer();
            buffer.writeBytes(message);
            if (channel == null) {
                if (future != null) {
                    future.awaitUninterruptibly(6000);
                    if (future.isCancelled()) {
                        // Connection attempt cancelled by user
                        if (JFSocketManager.getInstance().onChannelActiveListener != null) {
                            JFSocketManager.getInstance().onChannelActiveListener.onChannelActiveFail();
                        }
                    } else if (!future.isSuccess()) {
                        // You might get a NullPointerException here because the future
                        // might not be completed yet.
                        future.cause().printStackTrace();
                        if (JFSocketManager.getInstance().onChannelActiveListener != null) {
                            JFSocketManager.getInstance().onChannelActiveListener.onChannelActiveFail();
                        }
                    } else {
                        // Connection established successfully
                        channel = future.channel();
                        channel.read();
                    }
                }
            }
            if (channel != null) {
                channel.writeAndFlush(buffer);//.addListener(new JFChannelFutureListener(messageID));
            } else {
                Log.e("--", "channel is null!!!---------");

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
